﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AnesSystem.Models;
using System.Collections.ObjectModel;
using AnesSystem.Services;
using AnesSystem.Controls;
using AnesSystem.ViewModels;
using System.Windows;
using System.ComponentModel;
using Common;

namespace AnesSystem
{
    public abstract class VitalSignDataCache
    {
        #region Variables
        protected Dictionary<String, Dictionary<DateTime, PatientVitalSignsModel>> _bedsideMapMap = new Dictionary<string, Dictionary<DateTime, PatientVitalSignsModel>>();
        protected ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> _besideLineObservableList = new ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>>();
        protected ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> _besideTableObservableList = new ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>>();
        protected ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> _bedsideObservableList = new ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>>();

        protected Dictionary<string, List<PatientVitalSignsModel>> vitalSignsMap;
        protected bool _isSubResp = false;

        protected List<PatientEventsModel> _respCtrlEventList = new List<PatientEventsModel>();
        protected List<PatientEventsModel> _respSubEventList = new List<PatientEventsModel>();

        protected List<PatientVitalSignsModel> tempList = new List<PatientVitalSignsModel>();

        private EventDataCache eventData;

        private string _patientId;

        #endregion


        #region Constructor
        public VitalSignDataCache()
        {
            VitalSignCapture.Instance.VitalSignCaptured += Instance_Captured;
        }


        #endregion


        #region Properties
        public Dictionary<string, Dictionary<DateTime, PatientVitalSignsModel>> BedsideMapMap
        {
            get
            {
                return _bedsideMapMap;
            }

            set
            {
                _bedsideMapMap = value;
            }
        }


        public ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> BesideTableObservableList
        {
            get
            {
                return _besideTableObservableList;
            }

            set
            {
                _besideTableObservableList = value;
            }
        }

        public ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> BesideLineObservableList
        {
            get
            {
                return _besideLineObservableList;
            }

            set
            {
                _besideLineObservableList = value;
            }
        }

        public ObservableCollection<Dictionary<DateTime, PatientVitalSignsModel>> BedsideObservableList
        {
            get
            {
                return _bedsideObservableList;
            }

            set
            {
                _bedsideObservableList = value;
            }
        }

        public List<PatientEventsModel> RespCtrlEventList
        {
            get
            {
                return _respCtrlEventList;
            }

            set
            {
                _respCtrlEventList = value;
            }
        }

        public List<PatientEventsModel> RespSubEventList
        {
            get
            {
                return _respSubEventList;
            }

            set
            {
                _respSubEventList = value;
            }
        }

        public bool IsSubResp
        {
            get
            {
                return _isSubResp;
            }

            set
            {
                _isSubResp = value;
            }
        }

        public PatientLinkModel CurPatientLink
        {
            get
            {
                return DataManager.Instance.CurrentPatientLink == null ? null : DataManager.Instance.CurrentPatientLink;
            }
        }

        protected EventDataCache EventData
        {
            get
            {
                return eventData;
            }

            set
            {
                eventData = value;
            }
        }

        public string PatientId
        {
            get
            {
                return _patientId;
            }

            set
            {
                _patientId = value;
            }
        }

        public Dictionary<string, List<PatientVitalSignsModel>> VitalSignsMap
        {
            get
            {
                return vitalSignsMap;
            }

            set
            {
                vitalSignsMap = value;
            }
        }
        #endregion


        #region 依赖属性


        #endregion


        #region Event

        public event EventHandler<CaptureVitalArgs> Captured;

        #endregion


        #region protectedMethods

        protected abstract void AddParamTimeData(int page);
        /// <summary>
        /// 创建单个生命体征
        /// </summary>
        /// <param name="vitalSigns"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        protected abstract PatientVitalSignsModel CreateBedside(ConfigVitalSignsModel vitalSigns, DateTime date);


        /// <summary>
        /// 参数值改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected abstract void PatientVitalSigns_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e);




        /// <summary>
        /// 加载生命体征历史数据
        /// </summary>
        /// <param name="bedsideMap"></param>
        /// <param name="vitalSigns"></param>
        /// <param name="date"></param>
        protected abstract void AddBedsideHistoryData(Dictionary<DateTime, PatientVitalSignsModel> bedsideMap, ConfigVitalSignsModel vitalSigns, DateTime date);

        protected void SetValue(Dictionary<DateTime, PatientVitalSignsModel> bedsideMap, PatientVitalSignsModel bedside)
        {

            PatientVitalSignsModel p = bedsideMap[bedside.CaptureTime];
            p.ModValue = bedside.ModValue;
            if (!DataManager.Instance.CurrentHospital.HospitalCode.Equals(HospitalConfig.HOSPITAL_CODE_CQ_TLRMYY))
            {
                CheckXueYa(p);
            }
            p.CaptureTime = bedside.CaptureTime;
            p.PatientID = bedside.PatientID;
            p.Id = bedside.Id;

        }

        private void CheckXueYa(PatientVitalSignsModel patientVitalSignsModel)
        {
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_IBP_S) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_NIBP_S))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_NIBP_S][patientVitalSignsModel.CaptureTime].ModValue))
                    {
                        BedsideMapMap[Constants.PARAM_NIBP_S][patientVitalSignsModel.CaptureTime].ModValue = "";
                    }
                }
            }
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_IBP_D) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_NIBP_D))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_NIBP_S][patientVitalSignsModel.CaptureTime].ModValue))
                    {
                        BedsideMapMap[Constants.PARAM_NIBP_D][patientVitalSignsModel.CaptureTime].ModValue = "";
                    }
                }
            }
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_IBP_M) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_NIBP_M))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_NIBP_S][patientVitalSignsModel.CaptureTime].ModValue))
                    {
                        BedsideMapMap[Constants.PARAM_NIBP_M][patientVitalSignsModel.CaptureTime].ModValue = "";
                    }
                }
            }

            //无创血压存储
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_NIBP_S) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_IBP_S))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_IBP_S][patientVitalSignsModel.CaptureTime].ModValue) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
                    {
                        patientVitalSignsModel.ModValue = "";
                    }
                }
            }
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_NIBP_D) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_IBP_D))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_IBP_D][patientVitalSignsModel.CaptureTime].ModValue) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
                    {
                        patientVitalSignsModel.ModValue = "";
                    }
                }
            }
            if (patientVitalSignsModel.Code.Equals(Constants.PARAM_NIBP_M) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
            {
                if (BedsideMapMap.ContainsKey(Constants.PARAM_IBP_M))
                {
                    if (!string.IsNullOrEmpty(BedsideMapMap[Constants.PARAM_IBP_M][patientVitalSignsModel.CaptureTime].ModValue) && !string.IsNullOrEmpty(patientVitalSignsModel.ModValue))
                    {
                        patientVitalSignsModel.ModValue = "";
                    }
                }
            }
        }

        protected void SetValueForResp(PatientVitalSignsModel bedside)
        {

            if (bedside.Code.Equals(Constants.PARAM_RESP_CODE) || bedside.Code.Equals(Constants.PARAM_SUB_RESP))
            {
                bedside.Group = Constants.RESP;

                //判断是否处于辅助呼吸

                if (IsInRespSubTime(bedside.CaptureTime))
                {
                    bedside.Code = Constants.PARAM_SUB_RESP;
                }
                else
                {
                    bedside.Code = Constants.PARAM_RESP_CODE;
                }

                //判断是否处于控制呼吸
                if (IsInRespCtrlTime(bedside.CaptureTime))
                {
                    bedside.ModValue = "";
                }

            }

            if (bedside.Code.Equals(Constants.PARAM_CTRL_RESP_CODE))
            {

                if (!IsInRespCtrlTime(bedside.CaptureTime))
                {
                    bedside.ModValue = "";
                    bedside.Group = Constants.PARAM_CTRL_RESP_CODE;
                }
                else
                {
                    bedside.Group = Constants.RESP;
                }
            }

        }

        protected abstract bool IsInRespCtrlTime(DateTime captureTime);


        protected abstract bool IsInRespSubTime(DateTime captureTime);


        /// <summary>
        /// 控制呼吸
        /// </summary>
        protected abstract void InitRespCtrlTime();


        /// <summary>
        /// 辅助呼吸
        /// </summary>
        protected abstract void InitRespSubTime();




        #endregion


        #region Public/ProtectedMethods



        public abstract void AddConfigParam(ConfigVitalSignsModel vitalSigns);
        public abstract void RemoveConfigParam(ConfigVitalSignsModel vitalSigns);
        /// <summary>
        /// 更改生命体征显示方式
        /// </summary>
        /// <param name="vitalSigns"></param>
        /// <param name="showMethod"></param>
        public void ChangeDataShowMethod(ConfigVitalSignsModel vitalSigns, int showMethod)
        {
            Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
            if (showMethod == Constants.BEDSIDE_SHOW_METHOD_TREND)
            {
                _besideLineObservableList.Add(bedsideMap);
                _besideTableObservableList.Remove(bedsideMap);
            }
            else
            {
                _besideLineObservableList.Remove(bedsideMap);
                _besideTableObservableList.Add(bedsideMap);
            }
        }
        /// <summary>
        /// 刷新呼吸事件
        /// </summary>
        public abstract void RefreshRespEvent();

        protected void InitSubRespData()
        {


            if (DataManager.Instance.Code2signs.ContainsKey(Constants.PARAM_RESP_CODE))
            {
                ConfigVitalSignsModel vitalSigns = DataManager.Instance.Code2signs[Constants.PARAM_RESP_CODE];
                if (_bedsideMapMap.ContainsKey(Constants.PARAM_RESP_CODE))
                {
                    Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
                    List<PatientVitalSignsModel> list = bedsideMap.Values.ToList();
                    foreach (var item in list)
                    {
                        SetValueForResp(item);
                    }
                }
                else
                {
                    if (DataManager.Instance.IsInAorP.Equals(Constants.ISANES))
                    {
                        RealTimeSignsConfigCtrlViewModel.Instance.ChangSignLeftToRightForResp(vitalSigns.code);
                    }
                    if (DataManager.Instance.IsInAorP.Equals(Constants.ISPACU))
                    {
                        PacuRealTimeSignsConfigCtrlViewModel.Instance.ChangSignLeftToRightForResp(vitalSigns.code);
                    }

                    Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
                    foreach (var item in bedsideMap.Values)
                    {
                        SetValueForResp(item);
                    }
                }

            }
        }
        protected void InitCtrlRespData()
        {
            if (RespCtrlEventList != null && RespCtrlEventList.Count > 0)
            {
                if (DataManager.Instance.Code2signs.ContainsKey(Constants.PARAM_CTRL_RESP_CODE))
                {
                    ConfigVitalSignsModel vitalSigns = DataManager.Instance.Code2signs[Constants.PARAM_CTRL_RESP_CODE];
                    if (_bedsideMapMap.ContainsKey(Constants.PARAM_CTRL_RESP_CODE))
                    {
                        Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
                        List<PatientVitalSignsModel> list = bedsideMap.Values.ToList();
                        foreach (var item in list)
                        {
                            SetValueForResp(item);
                        }
                    }
                    else
                    {
                        if (DataManager.Instance.IsInAorP.Equals(Constants.ISANES))
                        {
                            RealTimeSignsConfigCtrlViewModel.Instance.ChangSignLeftToRightForResp(vitalSigns.code);
                        }
                        if (DataManager.Instance.IsInAorP.Equals(Constants.ISPACU))
                        {
                            PacuRealTimeSignsConfigCtrlViewModel.Instance.ChangSignLeftToRightForResp(vitalSigns.code);
                        }
                        Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
                        foreach (var item in bedsideMap.Values)
                        {
                            SetValueForResp(item);
                        }
                    }

                }
            }
            else
            {
                if (DataManager.Instance.Code2signs.ContainsKey(Constants.PARAM_CTRL_RESP_CODE))
                {
                    ConfigVitalSignsModel vitalSigns = DataManager.Instance.Code2signs[Constants.PARAM_CTRL_RESP_CODE];
                    if (_bedsideMapMap.ContainsKey(Constants.PARAM_CTRL_RESP_CODE))
                    {
                        Dictionary<DateTime, PatientVitalSignsModel> bedsideMap = _bedsideMapMap[vitalSigns.code];
                        List<PatientVitalSignsModel> list = bedsideMap.Values.ToList();
                        foreach (var item in list)
                        {
                            SetValueForResp(item);
                        }
                    }
                }
            }
        }

        protected void ClearResp()
        {
            RespCtrlEventList.Clear();
            RespSubEventList.Clear();

        }

        public void ClearCache()
        {
            _bedsideObservableList.Clear();
            _besideLineObservableList.Clear();
            _besideTableObservableList.Clear();
            _bedsideMapMap.Clear();
        }
        public PatientVitalSignsModel CovertResp(PatientVitalSignsModel patientVitalSignsModel)
        {
            if (patientVitalSignsModel != null)
            {
                patientVitalSignsModel.Group = Constants.RESP;
                if (patientVitalSignsModel.Code.Equals(Constants.PARAM_RESP_CODE))
                {
                    bool isChange = false;
                    if (IsInRespCtrlTime(patientVitalSignsModel.CaptureTime))
                    {
                        Common.LogHelper.Info(this.GetType(), "RespData...., Anes capturing data，and value is changed to null, the data Code: " + patientVitalSignsModel.Code + "-- InitValue：" + patientVitalSignsModel.ModValue + "--captureTime" + patientVitalSignsModel.CaptureTime.ToString(DateFormat.DATE_FORMAT_STR_YMDHMS));
                        patientVitalSignsModel.ModValue = "";
                        isChange = true;
                    }
                    if (IsInRespSubTime(patientVitalSignsModel.CaptureTime))
                    {
                        Common.LogHelper.Info(this.GetType(), "RespData...., Anes capturing data，and code is changed to subResp, the data Code: " + patientVitalSignsModel.Code + "-- InitValue：" + patientVitalSignsModel.ModValue + "--captureTime" + patientVitalSignsModel.CaptureTime.ToString(DateFormat.DATE_FORMAT_STR_YMDHMS));
                        patientVitalSignsModel.Code = Constants.PARAM_SUB_RESP;
                        isChange = true;
                    }
                    if (!isChange)
                    {
                        Common.LogHelper.Info(this.GetType(), "RespData...., Anes capturing data，and is no change, the data Code: " + patientVitalSignsModel.Code + "-- InitValue：" + patientVitalSignsModel.ModValue + "--captureTime" + patientVitalSignsModel.CaptureTime.ToString(DateFormat.DATE_FORMAT_STR_YMDHMS));
                    }
                }
                if (patientVitalSignsModel.Code.Equals(Constants.PARAM_CTRL_RESP_CODE))
                {
                    bool isChange = false;
                    if (!IsInRespCtrlTime(patientVitalSignsModel.CaptureTime))
                    {
                        Common.LogHelper.Info(this.GetType(), "RespData...., Anes capturing data，and value is changed to null, the data Code: " + patientVitalSignsModel.Code + "-- InitValue：" + patientVitalSignsModel.ModValue + "--captureTime" + patientVitalSignsModel.CaptureTime.ToString(DateFormat.DATE_FORMAT_STR_YMDHMS));
                        patientVitalSignsModel.ModValue = "";
                        isChange = true;
                    }
                    if (!isChange)
                    {
                        Common.LogHelper.Info(this.GetType(), "RespData...., Anes capturing data，and is no change, the data Code: " + patientVitalSignsModel.Code + "-- InitValue：" + patientVitalSignsModel.ModValue + "--captureTime" + patientVitalSignsModel.CaptureTime.ToString(DateFormat.DATE_FORMAT_STR_YMDHMS));
                    }
                }
            }
            return patientVitalSignsModel;
        }
        protected abstract void ChangeVitalCache(PatientVitalSignsModel pvm);

        public virtual void RefreshLaborData()
        {
        }

        #endregion


        #region EventHandlers
        private void Instance_Captured(object sender, CaptureVitalArgs e)
        {
            Captured?.Invoke(this, e);
        }


        #endregion



    }
}
